from tkinter import *
from tkinter import ttk # 导入ttk模块，下拉菜单控件位于ttk子模块中
from random import randint
import random
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import datetime

def get_expression():  # 算式的生成
    num_scape = int(cbox1.get())
    a = randint(0, num_scape)
    b = randint(0, num_scape)  # 随机生成1~20之间的整数
    cal_scape = cbox2.get()
    if cal_scape == '加减运算':
        sign = random.choice(['＋', '－'])  # 随机进行＋，－运算
    elif cal_scape == '乘除运算':
        sign = random.choice(['×', '÷'])  # 随机进行x，÷运算
    else:
        sign = random.choice(['＋', '－', '×', '÷'])  # 随机进行x，÷运算

    ans_result = 0
    # ans = 0
    if sign == '＋':
        ans = a + b
    elif sign == '－':
        ans = a - b
    elif sign == '×':
        ans = a * b
    else:
        b = randint(1, num_scape)
        ans = int(a / b)
        ans_result = a % b
    if ans < 0 or ans > num_scape or ans_result != 0: # 如果结果不在0-100之间 则重新生成a b
        get_expression()
    else:
        # a,b,ans格式化，统一为2个宽度 使输出更整齐，美观
        # 存放 带没有（ex1）答案  和 有答案（ex2） 的算式
        ex2 = f'{a:<2}{sign}{b:<2}={ans:<2}'
        checkbox_value = checkbox_var.get()
        if checkbox_value == 1:
            rand_fill = randint(1, num_scape)
        else:
            rand_fill = 1

        if rand_fill % 5 == 0:
            ex1 = f'__{sign}{b:<2}={ans:<2}'
        elif rand_fill % 7 == 0:
            ex1 = f'{a:<2}{sign}__={ans:<2}'
        else:
            ex1 = f'{a:<2}{sign}{b:<2}=  '
        if a == 0 or b == 0:
            ex1 = f'{a:<2}{sign}{b:<2}=  '
        global expression
        expression = list()
        expression.append(ex1)
        expression.append(ex2)
    return expression  # 得到的两个算式以列表的形式返回

def save_expression():  # 得到指定数量的算式
    expression_Noans = list()  # 不带有答案
    expression_withans = list()  # 带有答案
    num_title = int(cbox0.get())
    for i in range(0, int(num_title)):  # 调用n次生成函数，得到n个满足条件的算式
        get_expression()
        # 却除重复的式子
        for i in range(0, len(expression_Noans)):
            if expression[0] == expression_Noans[i]:
                get_expression()
        # 却除重复的式子
        for i in range(0, len(expression_withans)):
            if expression[1] == expression_withans[i]:
                get_expression()
        expression_Noans.append(expression[0])
        expression_withans.append(expression[1])
    return [expression_Noans, expression_withans]  # 返回的expression_Noans,expression_withans列表中各有n个算式

def show_expression():  # 算式的输出和打印
    doc1 = Document()
    doc2 = Document()
    style1 = doc1.styles['Normal']
    style1.font.name = '宋体'
    style2 = doc2.styles['Normal']
    style2.font.name = '宋体'

    name = message_box.get()
    num_title = int(cbox0.get())
    lis = save_expression()
    expression_Noans = lis[0]
    expression_withans = lis[1]

    show_number1 = 0  # 用于记录每行输出的题量 控制排版
    show_number2 = 0  # 用于记录每行输出的题量 控制排版
    heading1 = doc1.add_heading(f'{name} 混合加减法题:',  0)
    heading1.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    heading2 = doc2.add_heading(f'{name} 混合加减法题(带答案):',  0)
    heading2.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    paragraph1 = doc1.add_paragraph(f'题目数：{num_title}题 日期：__年__月__日 用时：_______ 得分：_______')
    paragraph1.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT

    str1 = ''
    for i in range(0, len(expression_Noans)):
        str1 = str1 + expression_Noans[i] + '       '
        show_number1 += 1
        if show_number1 % 5 == 0:  # 每行输出五个题
            doc1.add_paragraph(str1)
            str1 = ''
        elif show_number1 == len(expression_Noans):
            doc1.add_paragraph(str1)

    paragraph2 = doc2.add_paragraph(f'题目数：{num_title}题 日期：__年__月__日 用时：_______ 得分：_______')
    paragraph2.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT

    str2 = ''
    for i in range(0, len(expression_withans)):
        str2 = str2 + expression_withans[i] + '       '
        show_number2 += 1
        if show_number2 % 5 == 0:  # 每行输出四个题
            doc2.add_paragraph(str2)
            str2 = ''
        elif show_number2 == len(expression_withans):
            doc2.add_paragraph(str2)
    noansw = "无答案版_" + str(datetime.datetime.now()).replace(":", "") + ".docx"
    withansw = "有答案版_" + str(datetime.datetime.now()).replace(":", "") + ".docx"
    doc1.save(noansw)
    doc2.save(withansw)

root = Tk()
root.geometry("400x300")
root.title("运算练习")

# 创建Canvas对象
canvas = Canvas(root)
canvas.pack()

# 创建LabelFrame对象
frame = LabelFrame(canvas, text="功能选择")
frame.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.8)

# 在LabelFrame中创建GUI组件
# 2. 创建测试者选项
label1= Label(frame, text="姓    名")
label1.grid(row=0, column=0, padx=(5, 0), pady=5)

message_box = Entry(frame)
message_box.insert(0,"可录入测试者姓名")
message_box.grid(row=0, column=1, columnspan=2, padx=(0, 5))


# 2. 创建题目数量选项
label2= Label(frame, text="题目数量")
label2.grid(row=1, column=0, padx=(5, 0), pady=5)

# 创建下拉菜单
cbox0 = ttk.Combobox(frame)
# 使用 grid() 来控制控件的位置
# 设置下拉菜单中的值
cbox0['value'] = ('10','20','50','100')
#通过 current() 设置下拉菜单选项的默认值
cbox0.current(3)
num_title = int(cbox0.get())
cbox0.grid(row=1, column=1, columnspan=2, padx=(0, 5))

# 3. 创建数字范围选项
label3= Label(frame, text="数字范围")
label3.grid(row=2, column=0, padx=(10, 0), pady=5)

# 创建下拉菜单
cbox1 = ttk.Combobox(frame)

# 设置下拉菜单中的值
cbox1['value'] = ('10', '20', '50', '100')
#通过 current() 设置下拉菜单选项的默认值
cbox1.current(1)
num_scape = int(cbox1.get())
cbox1.grid(row=2, column=1, columnspan=2, padx=(0, 5))


# 4. 创建题型范围选项
label4= Label(frame, text="题型范围")
label4.grid(row=3, column=0, padx=(5, 0), pady=5)

# 创建下拉菜单
cbox2 = ttk.Combobox(frame)
# 设置下拉菜单中的值
cbox2['value'] = ('加减运算', '乘除运算', '加减乘除')
#通过 current() 设置下拉菜单选项的默认值
cbox2.current(0)
cal_scape = cbox2.get()
cbox2.grid(row=3, column=1, columnspan=2, padx=(0, 5))


# 5. 创建是否填写选项
label5= Label(frame, text="有填空")
label5.grid(row=4, column=0, padx=(5, 0), pady=5)

# 创建下拉菜单
# 创建一个IntVar变量以存储复选框的值
checkbox_var = IntVar()
cbox3 = ttk.Checkbutton(frame,  text="是", variable=checkbox_var)
checkbox_value = checkbox_var.get()
# 设置下拉菜单中的值
cbox3.grid(row=4, column=1, columnspan=2, padx=(0, 5))

start_button = Button(frame, highlightthickness=0, text='开始', command=show_expression)
start_button.grid(row=5, column=1, ipadx=5)

quit_button = Button(frame, highlightthickness=0, text='退出', command=root.quit)
quit_button.grid(row=5, column=2, ipadx=5)


# 启动Tkinter事件循环
root.mainloop()
